﻿using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Principal;
using System.Text;

namespace VIID.Client
{
    public partial class Client
    {
        public double _timeSpan = 0;//计时器
        public HttpClient _httpClient;
        public global::System.Timers.Timer _timer;//保活定时器
        public ClientOptions _options;//客户端配置
        public class ClientOptions
        {
            /// <summary>
            /// 最后通信时间(最后通信时间+超时时间=保活)
            /// </summary>
            public long liveTime { get; set; }
            /// <summary>
            /// 操作序号
            /// </summary>
            private int _indexNum { get; set; } = 1;
            /// <summary>
            /// 设备ID
            /// </summary>
            public string deviceID { get; set; }
            /// <summary>
            /// 协议
            /// </summary>
            public string protocol { get; set; } = "http";
            /// <summary>
            /// 1400服务器地址
            /// </summary>
            public string server { get; set; }
            /// <summary>
            /// 1400端口
            /// </summary>
            public int port { get; set; } = 1400;
            /// <summary>
            /// 视频通道ID
            /// </summary>
            public string videoID { get; set; }
            /// <summary>
            /// 用户名
            /// </summary>
            public string userName { get; set; }
            /// <summary>
            /// 密码
            /// </summary>
            public string password { get; set; }
            /// <summary>
            /// 保活时间
            /// </summary>
            public int keepLiveInterval { get; set; } = 90 * 1000;
            /// <summary>
            /// 注册状态
            /// </summary>
            public bool State { get; set; } = false;
            /// <summary>
            /// 默认构造
            /// </summary>
            public ClientOptions()
            {
                this.liveTime = Utils.GetTimeStamp(DateTime.Now);
            }
            /// <summary>
            /// 服务器地址
            /// </summary>
            public string baseServer
            {
                get
                {
                    return string.Format("{0}://{1}:{2}", protocol, server, port);
                }
            }
            /// <summary>
            /// 获取操作序号
            /// </summary>
            /// <returns></returns>
            public string OperationNum()
            {
                _indexNum = (_indexNum >= 99999) ? 1 : _indexNum++;
                return string.Format("{0:D5}", this._indexNum);
            }
        }

        public Client()//默认构造
        {
            _httpClient = new HttpClient()
            {
                //BaseAddress = new Uri(_options.baseServer),
                Timeout = new TimeSpan(0, 0, 10)
            };

            _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/VIID+JSON"));
            _httpClient.DefaultRequestHeaders.Add("User-Agent", "VIIDClient/1.0");
            //_timer = new System.Timers.Timer();
            //_timer.Enabled = true;
            //_timer.Interval = 1000 * 60;
            //_timer.Elapsed += _timer_Elapsed;

        }

        public void Dispose()
        {
            this.Dispose(true);

            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (_options.State)
                UnRegister();

            _timer.Dispose();
        }
        /// <summary>
        /// 设置客户端参数
        /// </summary>
        /// <param name="options"></param>
        public void setOptions(ClientOptions options)
        {
            _options = options;
            _httpClient.DefaultRequestHeaders.Add("User-Identify", _options.deviceID);
            _httpClient.BaseAddress = new Uri(_options.baseServer);
            if (_options.baseServer.StartsWith("https"))
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

            _timer = new System.Timers.Timer();
            //_timer.Enabled = true;
            _timer.Interval = _options.keepLiveInterval;
            _timer.Elapsed += _timer_Elapsed;

        }
        /// <summary>
        /// 状态变更
        /// </summary>
        /// <param name="state"></param>
        public void onChangeState(bool state)
        {
            _options.State = state;
            if (_options.State)
            {
                _timer.Enabled = true;
                //_timer.Elapsed += _timer_Elapsed;
            }
            else
            {
                _timer.Enabled = false;
            }

        }
        /// <summary>
        /// 基本对象及数据组织库统一标识编码
        /// </summary>
        /// <param name="str1">设备编码/平台编码(20位)
        /// GB/T 28181-2016附录D中D.1规定的编码规则
        /// </param>
        /// <param name="str2">子类型编码(2位)
        /// 01-视频片段,02-图像,03-文件,04-保留,05-人脸库,06-人员库,07-机动车库,08-非机动车库,09-物品库,10-场景库,99-其他
        /// </param>
        /// <param name="str3">时间编码(14位)
        /// YYYYMMDDhhmmss，年月日时分秒，其中hh以24小时制表示
        /// </param>
        /// <param name="str4">序号(5位)
        /// 序号由阿拉伯数字000001起始顺序表示</param>
        /// <returns></returns>
        public static string GETID(string str1, string str2, string str3, int str4)
        {
            return string.Format("{0:D20}{1:D2}{2:D14}{3:D5}", str1, str2, str3, str4);
        }
        /// <summary>
        /// 自动保活
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _timer_Elapsed(object sender, global::System.Timers.ElapsedEventArgs e)//保活
        {
            if (_options.State && (_options.liveTime - Utils.GetTimeStamp(DateTime.Now)) >= _options.keepLiveInterval - 1)
            {
                _options.State = keepAlive();
            }
          
#if DEBUG
            Console.WriteLine("{0}自动保活,ID:{1}", DateTime.Now, _options.deviceID);
#endif
        }


        public bool Submit(string URI, byte[] content)
        {
            string postData = Encoding.UTF8.GetString(content);
            //Console.WriteLine(postData);
            HttpContent _httpContent = Utils.content(postData);

            try
            {
                HttpResponseMessage response = _httpClient.PostAsync(URI, _httpContent).Result;
                return (response.StatusCode == HttpStatusCode.OK);
            }
            catch (Exception e)
            {
                return false;
            }
        }

    




    }
}
